﻿using Library.Common.Common;
using Library.Common.Model;
using Library.Common.Serialize;
using Library.Core.Application;
using Library.Core.Application.BaseAction;
using Library.Core.Application.IInfrastructure;
using Synthesize.BaseSet.Domain.Aggregation.Entity.Authority;
using Synthesize.BaseSet.Domain.Repository.Authority;
using Synthesize.BaseSet.Domain.Specifications.Authority.Department;
using Synthesize.BaseSet.ServiceInterface.Dtos.Authority.Department;
using Synthesize.BaseSet.ServiceInterface.UseCase.Authority;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Synthesize.BaseSet.Application.UseCase.Authority
{
    /// <summary>
    /// 部门操作逻辑类
    /// </summary>
    public class DepartmentService : BaseService, IDepartmentService
    {

        private readonly IDepartmentRepository _departmentRepository;
        private readonly IUserDepartmentRepository _userDepartmentRepository;


        public DepartmentService(IIocContainer container
            , IDepartmentRepository departmentRepository
            , IUserDepartmentRepository userDepartmentRepository
            ) : base(container)
        {
            _departmentRepository = departmentRepository;
            _userDepartmentRepository = userDepartmentRepository;
        }

        /// <summary>
        /// 创建部门
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseApiResult<bool>> Create(CreateDepartmentInput input)
        {
            return await HandleAsync(input, async () =>
            {
                var department = MapperHelper<CreateDepartmentInput, DepartmentInfoEntity>.Map(input);
                department.Id = GuidHelper.GetSecuentialGuid();

                //添加部门判断逻辑
                await new CreateDepartmentSpecification(_departmentRepository).SatisfiedBy(department);

                _departmentRepository.Add(department);
                return await _departmentRepository.SaveAsync();
            });
        }

        /// <summary>
        /// 更新部门
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseApiResult<bool>> Update(UpdateDepartmentInput input)
        {
            return await HandleAsync(input, async () =>
            {
                var department = MapperHelper<UpdateDepartmentInput, DepartmentInfoEntity>.Map(input);
                //更新部门判断逻辑
                await new UpdateDepartmentSpecification(_departmentRepository).SatisfiedBy(department);
                _departmentRepository.Update(department);

                return await _departmentRepository.SaveAsync();
            });
        }

        /// <summary>
        /// 更新部门-用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseApiResult<bool>> UpdateDepartmentUser(UpdateUserDepartmentInput input)
        {
            return await HandleAsync(input, async () =>
            {
                var userDepartments = await _userDepartmentRepository.GetManyAsync(x => !input.DepartmentId.Equals(x.DepartmentId)&& input.UserIdList.Contains(x.UserId));
                if (userDepartments.Any())
                {
                    throw new ApplicationsException($"不允许一个人员属于多个部门！");
                }

                var userDepartmentList = await _userDepartmentRepository.GetManyAsync(x => input.DepartmentId.Equals(x.DepartmentId));
                if (userDepartmentList.Any())
                {
                    _userDepartmentRepository.UpdateIsDeletedRange(userDepartmentList);
                }

                var addUserDepartments = new List<UserDepartmentReEntity>();
                if (input.UserIdList.Any())
                {
                    foreach (var item in input.UserIdList)
                    {
                        addUserDepartments.Add(new UserDepartmentReEntity()
                        {
                            Id = GuidHelper.GetSecuentialGuid(),
                            DepartmentId = input.DepartmentId,
                            UserId = item
                        });
                    }
                    await _userDepartmentRepository.AddRangeAsync(addUserDepartments);
                }
                return await _userDepartmentRepository.SaveAsync();
            });
        }

        /// <summary>
        /// 删除部门
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseApiResult<bool>> DeleteById(SingleDeleteInput input)
        {

            return await HandleAsync(input, async () =>
            {
                var department = await _departmentRepository.GetAsync(input.Id);
                if (department == null)
                {
                    throw new ApplicationsException("无对应部门信息存在！");
                }
                await new DeleteDepartmentSpecification(_departmentRepository, _userDepartmentRepository).SatisfiedBy(department);
                _departmentRepository.UpdateIsDeleted(department);

                //删除部门-用户关系
                var oldUserDepartmentList = await _userDepartmentRepository.GetManyAsync(x => x.DepartmentId.Equals(input.Id));
                if (oldUserDepartmentList.Any())
                {
                    foreach (var userDep in oldUserDepartmentList)
                    {
                        _userDepartmentRepository.Delete(userDep);
                    }
                }

                return await _departmentRepository.SaveAsync();
            });
        }

        /// <summary>
        /// 删除指定的用户-部门关系
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BaseApiResult<bool>> DeleteUserDepartment(DeleteUserDepartmentInput input)
        {
            return await HandleAsync(input, async () =>
            {
                var userDepartment = await _userDepartmentRepository.GetAsync(x => input.DepartmentId.Equals(x.DepartmentId) && input.UserId.Equals(x.UserId));
                if (userDepartment != null)
                {
                    _userDepartmentRepository.UpdateIsDeleted(userDepartment);
                }
                return await _userDepartmentRepository.SaveAsync();
            });
        }
    }
}
